package classificator.database;

import classificator.database.TableSchema.Column;
import java.sql.ResultSet;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**gestire i dati contenuti in una tabella. 
 * Al suo interno è innestata la classe Tuple_Data utilizzata per gestire una tupla della tabella
 *
 * @author 
 */
public class TableData {

    public TableData() {}
    
    /**Interroga la tabella passata in input. 
     * Dopo aver effettuato la selezione di tutte le tuple della tabella, 
     * per ogni tupla controlla se un elemento è string oppure number
     * (consideriamo solo questi due tipi) e lo aggiunge alla tupla corrente. 
     * Infine aggiunge la tupla alla lista di tuple da restituire in uscita
     * 
     * @param table nome tabella da interrogare
     * @return lista di tuple
     * @throws SQLException 
     */
    public List<TupleData> getTransazioni(String table) throws ClassTypeException, SQLException {
        String cte = "acquisito un tipo diverso da quello atteso nell'acquisizione del training set";
        LinkedList<TupleData> transSet = new LinkedList<TupleData>();
	TableSchema ts = new TableSchema(table);
	Statement stmt = DbAccess.getConnection().createStatement(); 
	ResultSet rs = stmt.executeQuery("SELECT *" +  " FROM "  + table); 
	while(rs.next()) {                      
            TupleData singleT = new TupleData();
            for(int n=0; n < rs.getMetaData().getColumnCount(); n++) {
                Column col = ts.getColumn(n);
                if(col.isNumber())
                    singleT.add(rs.getFloat(ts.getColumn(n).getColumnName()));
                else if (col.isString())
                    singleT.add(rs.getString(ts.getColumn(n).getColumnName()));    
                else 
                    throw new ClassTypeException(cte);
            }
            transSet.add(singleT);
	}
	rs.close();
        return transSet;
    }

    /**
     * 
     * @param table Tabella da interrogare
     * @param column colonna da interrogare
     * @param modality modalità di query (con o senza DISTINCT)
     * @return Lista dei valori di un attributo.
     * @throws SQLException 
     */
    public List<Object> getColumnValues(String table, Column column, QUERY_TYPE modality) throws SQLException {
        LinkedList<Object> valueSet = new LinkedList<Object>();
        String sql = "SELECT ";
        if (modality.equals(QUERY_TYPE.DISTINCT))
            sql += "DISTINCT ";
        sql += column.getColumnName() + " FROM " + table + " ORDER BY " + column.getColumnName();
        Statement stmt = DbAccess.getConnection().createStatement(); 
        ResultSet rs = stmt.executeQuery(sql);
        while(rs.next()){
            valueSet.add(rs.getObject(1));
        }
        rs.close();
        return valueSet;
    }
    
    public class TupleData {
        private List<Object> tuple = new ArrayList<Object>();
        
        public void add(Object obj){
            tuple.add(obj);
        }
        
        public Object get(int i){
            return tuple.get(i);
        }
        
        public int size(){
            return tuple.size();
        }
        
        @Override
        public String toString() {
            String value = "";
            Iterator<Object> it = tuple.iterator();
            while (it.hasNext()) {
                value += (it.next().toString() + " ");
            }
            return value;
        }
    }
}